package com.nanhai.buddhist.college.module.study.service.studyplan;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.nanhai.buddhist.college.framework.common.util.collection.CollectionUtils;
import com.nanhai.buddhist.college.module.study.dal.dataobject.studyplan.StudyPlanSubjectDO;
import com.nanhai.buddhist.college.module.study.dal.dataobject.studyplan.StudyPlanTeacherDO;
import com.nanhai.buddhist.college.module.study.dal.mysql.studyplan.StudyPlanSubjectMapper;
import com.nanhai.buddhist.college.module.study.dal.mysql.studyplan.StudyPlanTeacherMapper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.util.*;
import java.util.stream.Collectors;

import com.nanhai.buddhist.college.module.study.controller.admin.studyplan.vo.*;
import com.nanhai.buddhist.college.module.study.dal.dataobject.studyplan.StudyPlanDO;
import com.nanhai.buddhist.college.framework.common.pojo.PageResult;

import com.nanhai.buddhist.college.module.study.convert.studyplan.StudyPlanConvert;
import com.nanhai.buddhist.college.module.study.dal.mysql.studyplan.StudyPlanMapper;

import static com.nanhai.buddhist.college.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.nanhai.buddhist.college.module.study.enums.ErrorCodeConstants.*;

/**
 * 教学计划 Service 实现类
 *
 * @author xqenzo@163.com
 */
@Service
@Validated
public class StudyPlanServiceImpl implements StudyPlanService {

    @Resource
    private StudyPlanMapper planMapper;

    @Resource
    private StudyPlanTeacherMapper studyPlanTeacherMapper;

    @Resource
    private StudyPlanSubjectMapper studyPlanSubjectMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String createPlan(StudyPlanCreateReqVO createReqVO) {
        // 插入
        StudyPlanDO plan = StudyPlanConvert.INSTANCE.convert(createReqVO);
        planMapper.insert(plan);
        String planId = plan.getId();

        // 插入教师信息
        List<StudyPlanTeacherDO> teacherDOList = createReqVO.getTeacherIds().stream().map(m -> StudyPlanTeacherDO.builder().studyPlanId(planId).teacherId(m).build()).collect(Collectors.toList());
        studyPlanTeacherMapper.insertBatch(teacherDOList);

        // 插入课程信息
        List<StudyPlanSubjectDO> studyPlanSubjectDOList = createReqVO.getSubjectIds().stream().map(m -> StudyPlanSubjectDO.builder().studyPlanId(planId).studySubjectId(m).build()).collect(Collectors.toList());
        studyPlanSubjectMapper.insertBatch(studyPlanSubjectDOList);
        // 返回
        return plan.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updatePlan(StudyPlanUpdateReqVO updateReqVO) {
        // 校验存在
        this.validatePlanExists(updateReqVO.getId());
        // 更新
        StudyPlanDO updateObj = StudyPlanConvert.INSTANCE.convert(updateReqVO);
        planMapper.updateById(updateObj);


        deleteInfoByPlanId(updateReqVO.getId());

        // 插入教师信息
        List<StudyPlanTeacherDO> teacherDOList = updateReqVO.getTeacherIds().stream().map(m -> StudyPlanTeacherDO.builder().studyPlanId(updateReqVO.getId()).teacherId(m).build()).collect(Collectors.toList());
        studyPlanTeacherMapper.insertBatch(teacherDOList);

        // 插入课程信息
        List<StudyPlanSubjectDO> studyPlanSubjectDOList = updateReqVO.getSubjectIds().stream().map(m -> StudyPlanSubjectDO.builder().studyPlanId(updateReqVO.getId()).studySubjectId(m).build()).collect(Collectors.toList());
        studyPlanSubjectMapper.insertBatch(studyPlanSubjectDOList);
    }

    private void deleteInfoByPlanId(String id) {
        // 删除教师信息
        studyPlanTeacherMapper.deleteByStudyPlanId(id);
        // 删除课程信息
        studyPlanSubjectMapper.deleteByStudyPlanId(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deletePlan(String id) {
        // 校验存在
        this.validatePlanExists(id);
        // 删除
        planMapper.deleteById(id);


        deleteInfoByPlanId(id);


    }

    private void validatePlanExists(String id) {
        if (planMapper.selectById(id) == null) {
            throw exception(PLAN_NOT_EXISTS);
        }
    }

    @Override
    public StudyPlanDO getPlan(String id) {
        StudyPlanDO studyPlanDO = planMapper.selectByIdDeep(id);

         List<StudyPlanTeacherDO> studyPlanTeacherDOS = studyPlanTeacherMapper.selectList(new LambdaQueryWrapper<StudyPlanTeacherDO>().eq(StudyPlanTeacherDO::getStudyPlanId, id));
        if (CollectionUtil.isNotEmpty(studyPlanTeacherDOS)) {
             List<String> collect = studyPlanTeacherDOS.stream().map(StudyPlanTeacherDO::getTeacherId).collect(Collectors.toList());
            studyPlanDO.setTeacherIds(collect);
        }
         List<StudyPlanSubjectDO> studyPlanSubjectDOS = studyPlanSubjectMapper.selectList(new LambdaQueryWrapper<StudyPlanSubjectDO>().eq(StudyPlanSubjectDO::getStudyPlanId, id));
        if (CollectionUtil.isNotEmpty(studyPlanSubjectDOS)) {
            List<String> collect = studyPlanSubjectDOS.stream().map(StudyPlanSubjectDO::getStudySubjectId).collect(Collectors.toList());
            studyPlanDO.setSubjectIds(collect);
        }
        return studyPlanDO;
    }

    @Override
    public List<StudyPlanDO> getPlanList(Collection<String> ids) {
        return CollectionUtils.isEmpty(ids) ? Collections.emptyList() : planMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<StudyPlanDO> getPlanPage(StudyPlanPageReqVO pageReqVO) {
        return planMapper.selectPage(pageReqVO);
    }

    @Override
    public List<StudyPlanDO> getPlanList(StudyPlanExportReqVO exportReqVO) {
        return planMapper.selectList(exportReqVO);
    }

}
